🎖️GitЯра🎖️
Node / meshtastic / Meshtastic-Android / files / feature / node / src / commonMain / kotlin / org / meshtastic / feature / node / metrics / TracerouteLog.kt
Displaying Raw • Download
feature/node/src/commonMain/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt 2d20cd8a4708e2ef66e98d5259f3a97ec93f240a (2d20cd8a) Text, 16.53 KB
T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tf0883e@fileTb4b4b4:Te6edf3SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72package T7ee787org.meshtastic.feature.node.metrics
Tff7b72import T7ee787androidx.compose.foundation.BorderStroke
Tff7b72import T7ee787androidx.compose.foundation.ExperimentalFoundationApi
Tff7b72import T7ee787androidx.compose.foundation.combinedClickable
Tff7b72import T7ee787androidx.compose.foundation.layout.Arrangement
Tff7b72import T7ee787androidx.compose.foundation.layout.Box
Tff7b72import T7ee787androidx.compose.foundation.layout.Column
Tff7b72import T7ee787androidx.compose.foundation.layout.FlowRow
Tff7b72import T7ee787androidx.compose.foundation.layout.Row
Tff7b72import T7ee787androidx.compose.foundation.layout.Spacer
Tff7b72import T7ee787androidx.compose.foundation.layout.fillMaxSize
Tff7b72import T7ee787androidx.compose.foundation.layout.fillMaxWidth
Tff7b72import T7ee787androidx.compose.foundation.layout.height
Tff7b72import T7ee787androidx.compose.foundation.layout.padding
Tff7b72import T7ee787androidx.compose.foundation.layout.width
Tff7b72import T7ee787androidx.compose.foundation.lazy.LazyColumn
Tff7b72import T7ee787androidx.compose.foundation.lazy.itemsIndexed
Tff7b72import T7ee787androidx.compose.material3.Card
Tff7b72import T7ee787androidx.compose.material3.CardDefaults
Tff7b72import T7ee787androidx.compose.material3.DropdownMenu
Tff7b72import T7ee787androidx.compose.material3.Icon
Tff7b72import T7ee787androidx.compose.material3.MaterialTheme
Tff7b72import T7ee787androidx.compose.material3.Text
Tff7b72import T7ee787androidx.compose.runtime.Composable
Tff7b72import T7ee787androidx.compose.runtime.getValue
Tff7b72import T7ee787androidx.compose.runtime.mutableStateOf
Tff7b72import T7ee787androidx.compose.runtime.remember
Tff7b72import T7ee787androidx.compose.runtime.setValue
Tff7b72import T7ee787androidx.compose.ui.Alignment
Tff7b72import T7ee787androidx.compose.ui.Modifier
Tff7b72import T7ee787androidx.compose.ui.graphics.Color
Tff7b72import T7ee787androidx.compose.ui.graphics.vector.ImageVector
Tff7b72import T7ee787androidx.compose.ui.text.AnnotatedString
Tff7b72import T7ee787androidx.compose.ui.text.buildAnnotatedString
Tff7b72import T7ee787androidx.compose.ui.text.font.FontWeight
Tff7b72import T7ee787androidx.compose.ui.unit.dp
Tff7b72import T7ee787androidx.lifecycle.compose.collectAsStateWithLifecycle
Tff7b72import T7ee787org.jetbrains.compose.resources.pluralStringResource
Tff7b72import T7ee787org.jetbrains.compose.resources.stringResource
Tff7b72import T7ee787org.meshtastic.core.common.util.DateFormatter
Tff7b72import T7ee787org.meshtastic.core.common.util.NumberFormatter
Tff7b72import T7ee787org.meshtastic.core.common.util.formatString
Tff7b72import T7ee787org.meshtastic.core.model.TracerouteOverlay
Tff7b72import T7ee787org.meshtastic.core.model.fullRouteDiscovery
Tff7b72import T7ee787org.meshtastic.core.model.getTracerouteResponse
Tff7b72import T7ee787org.meshtastic.core.model.util.TimeConstants.MS_PER_SEC
Tff7b72import T7ee787org.meshtastic.core.resources.Res
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_diff
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_direct
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_duration
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_forward_hops
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_hops
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_log
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_no_response
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_return_hops
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_round_trip
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_route_back_to_us
Tff7b72import T7ee787org.meshtastic.core.resources.traceroute_route_towards_dest
Tff7b72import T7ee787org.meshtastic.core.ui.icon.Group
Tff7b72import T7ee787org.meshtastic.core.ui.icon.MeshtasticIcons
Tff7b72import T7ee787org.meshtastic.core.ui.icon.PersonOff
Tff7b72import T7ee787org.meshtastic.core.ui.icon.Refresh
Tff7b72import T7ee787org.meshtastic.core.ui.icon.Route
Tff7b72import T7ee787org.meshtastic.core.ui.theme.GraphColors
Tff7b72import T7ee787org.meshtastic.core.ui.theme.StatusColors.StatusGreen
Tff7b72import T7ee787org.meshtastic.core.ui.theme.StatusColors.StatusOrange
Tff7b72import T7ee787org.meshtastic.core.ui.theme.StatusColors.StatusYellow
Tff7b72import T7ee787org.meshtastic.core.ui.util.annotateTraceroute
Tff7b72import T7ee787org.meshtastic.feature.node.component.CooldownIconButton
Tff7b72import T7ee787org.meshtastic.proto.RouteDiscovery
T8b949e/**
* Full-screen traceroute log with chart and card list, built on [BaseMetricScreen]. Shows forward/return hops and
* round-trip duration over time. Supports time-frame filtering, chart expand/collapse, and card-to-chart
* synchronisation.
*/
Tf0883e@OptInTb4b4b4(Te6edf3ExperimentalFoundationApiTff7b72::Te6edf3classTb4b4b4)
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffLongMethodTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffCyclomaticComplexMethodTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffUnusedParameterTa5d6ff"Tb4b4b4)
Tf0883e@Composable
Tff7b72fun Td2a8ffTracerouteLogScreenTb4b4b4(
Te6edf3modifierTb4b4b4: Te6edf3Modifier Tff7b72= Te6edf3ModifierTb4b4b4,
Te6edf3viewModelTb4b4b4: Te6edf3MetricsViewModelTb4b4b4,
Te6edf3onNavigateUpTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Te6edf3onViewOnMapTb4b4b4: Tb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3responseLogUuidTb4b4b4: Tffa657StringTb4b4b4) Tff7b72-Tff7b72> Tffa657Unit Tff7b72= Tb4b4b4{ Te6edf3_Tb4b4b4, Te6edf3_ Tff7b72-Tff7b72> Tb4b4b4}Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3state Tff7b72by Te6edf3viewModelTb4b4b4.Te6edf3stateTb4b4b4.Te6edf3collectAsStateWithLifecycleTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3timeFrame Tff7b72by Te6edf3viewModelTb4b4b4.Te6edf3timeFrameTb4b4b4.Te6edf3collectAsStateWithLifecycleTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3availableTimeFrames Tff7b72by Te6edf3viewModelTb4b4b4.Te6edf3availableTimeFramesTb4b4b4.Te6edf3collectAsStateWithLifecycleTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3lastTracerouteTime Tff7b72by Te6edf3viewModelTb4b4b4.Te6edf3lastTraceRouteTimeTb4b4b4.Te6edf3collectAsStateWithLifecycleTb4b4b4(Tb4b4b4)
Tff7b72fun Td2a8ffgetUsernameTb4b4b4(Te6edf3nodeNumTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657String Tff7b72= Te6edf3withTb4b4b4(Te6edf3viewModelTb4b4b4.Te6edf3getUserTb4b4b4(Te6edf3nodeNumTb4b4b4)Tb4b4b4) Tb4b4b4{ Ta5d6ff"Tffd700$Te6edf3long_nameTa5d6ff (Tffd700$Te6edf3short_nameTa5d6ff)Ta5d6ff" Tb4b4b4}
Tff7b72val Te6edf3statusGreen Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3StatusGreen
Tff7b72val Te6edf3statusYellow Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3StatusYellow
Tff7b72val Te6edf3statusOrange Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3StatusOrange
Tff7b72val Te6edf3headerTowardsStr Tff7b72= Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_route_towards_destTb4b4b4)
Tff7b72val Te6edf3headerBackStr Tff7b72= Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_route_back_to_usTb4b4b4)
Tff7b72val Te6edf3durationFormatStr Tff7b72= Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_durationTb4b4b4)
Tff7b72val Te6edf3threshold Tff7b72= Te6edf3timeFrameTb4b4b4.Te6edf3timeThresholdTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3filteredRequests Tff7b72=
Te6edf3rememberTb4b4b4(Te6edf3stateTb4b4b4.Te6edf3tracerouteRequestsTb4b4b4, Te6edf3thresholdTb4b4b4) Tb4b4b4{
Te6edf3stateTb4b4b4.Te6edf3tracerouteRequestsTb4b4b4.Te6edf3filter Tb4b4b4{ Tb4b4b4(Tffa657itTb4b4b4.Te6edf3received_date Tff7b72/ Te6edf3MS_PER_SECTb4b4b4) Tff7b72>Tff7b72= Te6edf3threshold Tb4b4b4}
Tb4b4b4}
Tff7b72val Te6edf3points Tff7b72=
Te6edf3rememberTb4b4b4(Te6edf3filteredRequestsTb4b4b4, Te6edf3stateTb4b4b4.Te6edf3tracerouteResultsTb4b4b4) Tb4b4b4{
Te6edf3resolveTraceroutePointsTb4b4b4(Te6edf3filteredRequestsTb4b4b4, Te6edf3stateTb4b4b4.Te6edf3tracerouteResultsTb4b4b4)
Tb4b4b4}
Te6edf3BaseMetricScreenTb4b4b4(
Te6edf3onNavigateUp Tff7b72= Te6edf3onNavigateUpTb4b4b4,
Te6edf3telemetryType Tff7b72= Tff7b72nullTb4b4b4,
Te6edf3titleRes Tff7b72= Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_logTb4b4b4,
Te6edf3nodeName Tff7b72= Te6edf3stateTb4b4b4.Te6edf3nodeTff7b72?.Te6edf3userTff7b72?.Te6edf3long_name Tff7b72?: Ta5d6ff"Ta5d6ff"Tb4b4b4,
Te6edf3data Tff7b72= Te6edf3pointsTb4b4b4,
Te6edf3timeProvider Tff7b72= Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3timeSeconds Tb4b4b4}Tb4b4b4,
Te6edf3infoData Tff7b72= Te6edf3TRACEROUTE_INFO_DATATb4b4b4,
Te6edf3extraActions Tff7b72= Tb4b4b4{
Tff7b72if Tb4b4b4(Tff7b72!Te6edf3stateTb4b4b4.Te6edf3isLocalTb4b4b4) Tb4b4b4{
Te6edf3CooldownIconButtonTb4b4b4(
Te6edf3onClick Tff7b72= Tb4b4b4{ Te6edf3viewModelTb4b4b4.Te6edf3requestTracerouteTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3cooldownTimestamp Tff7b72= Te6edf3lastTracerouteTimeTb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3IconTb4b4b4(Te6edf3imageVector Tff7b72= Te6edf3MeshtasticIconsTb4b4b4.Te6edf3RefreshTb4b4b4, Te6edf3contentDescription Tff7b72= Tff7b72nullTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Te6edf3controlPart Tff7b72= Tb4b4b4{
Te6edf3TimeFrameSelectorTb4b4b4(
Te6edf3selectedTimeFrame Tff7b72= Te6edf3timeFrameTb4b4b4,
Te6edf3availableTimeFrames Tff7b72= Te6edf3availableTimeFramesTb4b4b4,
Te6edf3onTimeFrameSelected Tff7b72= Te6edf3viewModelTff7b72::Te6edf3setTimeFrameTb4b4b4,
Te6edf3modifier Tff7b72= Te6edf3ModifierTb4b4b4.Te6edf3paddingTb4b4b4(Te6edf3horizontal Tff7b72= T79c0ff1T79c0ff6.Te6edf3dpTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}Tb4b4b4,
Te6edf3chartPart Tff7b72= Tb4b4b4{ Te6edf3chartModifierTb4b4b4, Te6edf3selectedXTb4b4b4, Te6edf3vicoScrollStateTb4b4b4, Te6edf3onPointSelected Tff7b72-Tff7b72>
Te6edf3TracerouteMetricsChartTb4b4b4(
Te6edf3modifier Tff7b72= Te6edf3chartModifierTb4b4b4,
Te6edf3points Tff7b72= Te6edf3pointsTb4b4b4.Te6edf3reversedTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3vicoScrollState Tff7b72= Te6edf3vicoScrollStateTb4b4b4,
Te6edf3selectedX Tff7b72= Te6edf3selectedXTb4b4b4,
Te6edf3onPointSelected Tff7b72= Te6edf3onPointSelectedTb4b4b4,
Tb4b4b4)
Tb4b4b4}Tb4b4b4,
Te6edf3listPart Tff7b72= Tb4b4b4{ Te6edf3listModifierTb4b4b4, Te6edf3selectedXTb4b4b4, Te6edf3lazyListStateTb4b4b4, Te6edf3onCardClick Tff7b72-Tff7b72>
Te6edf3LazyColumnTb4b4b4(Te6edf3modifier Tff7b72= Te6edf3listModifierTb4b4b4.Te6edf3fillMaxSizeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3state Tff7b72= Te6edf3lazyListStateTb4b4b4) Tb4b4b4{
Te6edf3itemsIndexedTb4b4b4(Te6edf3pointsTb4b4b4, Te6edf3key Tff7b72= Tb4b4b4{ Te6edf3_Tb4b4b4, Te6edf3point Tff7b72-Tff7b72> Te6edf3pointTb4b4b4.Te6edf3requestTb4b4b4.Te6edf3uuid Tb4b4b4}Tb4b4b4) Tb4b4b4{ Te6edf3_Tb4b4b4, Te6edf3point Tff7b72-Tff7b72>
Te6edf3TracerouteCardTb4b4b4(
Te6edf3point Tff7b72= Te6edf3pointTb4b4b4,
Te6edf3isSelected Tff7b72= Te6edf3pointTb4b4b4.Te6edf3timeSeconds Tff7b72=Tff7b72= Te6edf3selectedXTb4b4b4,
Te6edf3onClick Tff7b72= Tb4b4b4{ Te6edf3onCardClickTb4b4b4(Te6edf3pointTb4b4b4.Te6edf3timeSecondsTb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3onLongClick Tff7b72= Tb4b4b4{ Te6edf3viewModelTb4b4b4.Te6edf3deleteLogTb4b4b4(Te6edf3pointTb4b4b4.Te6edf3requestTb4b4b4.Te6edf3uuidTb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3onShowDetail Tff7b72= Tb4b4b4{
Te6edf3showTracerouteDetailTb4b4b4(
Te6edf3point Tff7b72= Te6edf3pointTb4b4b4,
Te6edf3viewModel Tff7b72= Te6edf3viewModelTb4b4b4,
Te6edf3getUsername Tff7b72= Tff7b72::Te6edf3getUsernameTb4b4b4,
Te6edf3headerTowards Tff7b72= Te6edf3headerTowardsStrTb4b4b4,
Te6edf3headerBack Tff7b72= Te6edf3headerBackStrTb4b4b4,
Te6edf3durationTemplate Tff7b72= Te6edf3durationFormatStrTb4b4b4,
Te6edf3statusGreen Tff7b72= Te6edf3statusGreenTb4b4b4,
Te6edf3statusYellow Tff7b72= Te6edf3statusYellowTb4b4b4,
Te6edf3statusOrange Tff7b72= Te6edf3statusOrangeTb4b4b4,
Te6edf3onViewOnMap Tff7b72= Te6edf3onViewOnMapTb4b4b4,
Tb4b4b4)
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
T8b949e/** A selectable card summarising a single traceroute request/response pair. */
Tf0883e@Composable
Tf0883e@OptInTb4b4b4(Te6edf3ExperimentalFoundationApiTff7b72::Te6edf3classTb4b4b4)
Tff7b72private Tff7b72fun Td2a8ffTracerouteCardTb4b4b4(
Te6edf3pointTb4b4b4: Te6edf3TraceroutePointTb4b4b4,
Te6edf3isSelectedTb4b4b4: Tffa657BooleanTb4b4b4,
Te6edf3onClickTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Te6edf3onLongClickTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Te6edf3onShowDetailTb4b4b4: Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3route Tff7b72= Te6edf3pointTb4b4b4.Te6edf3resultTff7b72?.Te6edf3fromRadioTff7b72?.Te6edf3packetTff7b72?.Te6edf3fullRouteDiscovery
Tff7b72val Te6edf3time Tff7b72= Te6edf3DateFormatterTb4b4b4.Te6edf3formatDateTimeTb4b4b4(Te6edf3pointTb4b4b4.Te6edf3requestTb4b4b4.Te6edf3received_dateTb4b4b4)
Tff7b72val Tb4b4b4(Te6edf3summaryTextTb4b4b4, Te6edf3iconTb4b4b4) Tff7b72= Te6edf3routeTb4b4b4.Te6edf3getTextAndIconTb4b4b4(Tb4b4b4)
Tff7b72var Te6edf3expanded Tff7b72by Te6edf3remember Tb4b4b4{ Te6edf3mutableStateOfTb4b4b4(Tff7b72falseTb4b4b4) Tb4b4b4}
Te6edf3Box Tb4b4b4{
Te6edf3CardTb4b4b4(
Te6edf3modifier Tff7b72=
Te6edf3ModifierTb4b4b4.Te6edf3fillMaxWidthTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3paddingTb4b4b4(Te6edf3horizontal Tff7b72= T79c0ff8.Te6edf3dpTb4b4b4, Te6edf3vertical Tff7b72= T79c0ff4.Te6edf3dpTb4b4b4)
Tb4b4b4.Te6edf3combinedClickableTb4b4b4(
Te6edf3onLongClick Tff7b72= Tb4b4b4{ Te6edf3expanded Tff7b72= Tff7b72true Tb4b4b4}Tb4b4b4,
Te6edf3onClick Tff7b72= Tb4b4b4{
Te6edf3onClickTb4b4b4(Tb4b4b4)
Te6edf3onShowDetailTb4b4b4(Tb4b4b4)
Tb4b4b4}Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3border Tff7b72= Tff7b72if Tb4b4b4(Te6edf3isSelectedTb4b4b4) Te6edf3BorderStrokeTb4b4b4(T79c0ff2.Te6edf3dpTb4b4b4, Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3primaryTb4b4b4) Tff7b72else Tff7b72nullTb4b4b4,
Te6edf3colors Tff7b72=
Te6edf3CardDefaultsTb4b4b4.Te6edf3cardColorsTb4b4b4(
Te6edf3containerColor Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3isSelectedTb4b4b4) Tb4b4b4{
Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3primaryContainer
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3surfaceVariant
Tb4b4b4}Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3TracerouteCardContentTb4b4b4(Te6edf3time Tff7b72= Te6edf3timeTb4b4b4, Te6edf3summaryText Tff7b72= Te6edf3summaryTextTb4b4b4, Te6edf3icon Tff7b72= Te6edf3iconTb4b4b4, Te6edf3point Tff7b72= Te6edf3pointTb4b4b4)
Tb4b4b4}
Te6edf3DropdownMenuTb4b4b4(Te6edf3expanded Tff7b72= Te6edf3expandedTb4b4b4, Te6edf3onDismissRequest Tff7b72= Tb4b4b4{ Te6edf3expanded Tff7b72= Tff7b72false Tb4b4b4}Tb4b4b4) Tb4b4b4{
Te6edf3DeleteItem Tb4b4b4{
Te6edf3onLongClickTb4b4b4(Tb4b4b4)
Te6edf3expanded Tff7b72= Tff7b72false
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e/** Card body showing timestamp, route summary text/icon, and metric indicators. */
Tf0883e@Composable
Tff7b72private Tff7b72fun Td2a8ffTracerouteCardContentTb4b4b4(Te6edf3timeTb4b4b4: Tffa657StringTb4b4b4, Te6edf3summaryTextTb4b4b4: Tffa657StringTb4b4b4, Te6edf3iconTb4b4b4: Te6edf3ImageVectorTb4b4b4, Te6edf3pointTb4b4b4: Te6edf3TraceroutePointTb4b4b4) Tb4b4b4{
Te6edf3ColumnTb4b4b4(Te6edf3modifier Tff7b72= Te6edf3ModifierTb4b4b4.Te6edf3paddingTb4b4b4(T79c0ff1T79c0ff2.Te6edf3dpTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3RowTb4b4b4(
Te6edf3modifier Tff7b72= Te6edf3ModifierTb4b4b4.Te6edf3fillMaxWidthTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3horizontalArrangement Tff7b72= Te6edf3ArrangementTb4b4b4.Te6edf3SpaceBetweenTb4b4b4,
Te6edf3verticalAlignment Tff7b72= Te6edf3AlignmentTb4b4b4.Te6edf3CenterVerticallyTb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3TextTb4b4b4(Te6edf3text Tff7b72= Te6edf3timeTb4b4b4, Te6edf3style Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3typographyTb4b4b4.Te6edf3titleMediumEmphasizedTb4b4b4, Te6edf3fontWeight Tff7b72= Te6edf3FontWeightTb4b4b4.Te6edf3BoldTb4b4b4)
Te6edf3IconTb4b4b4(Te6edf3imageVector Tff7b72= Te6edf3iconTb4b4b4, Te6edf3contentDescription Tff7b72= Tff7b72nullTb4b4b4, Te6edf3tint Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3onSurfaceVariantTb4b4b4)
Tb4b4b4}
Te6edf3SpacerTb4b4b4(Te6edf3modifier Tff7b72= Te6edf3ModifierTb4b4b4.Te6edf3heightTb4b4b4(T79c0ff4.Te6edf3dpTb4b4b4)Tb4b4b4)
Te6edf3TextTb4b4b4(
Te6edf3text Tff7b72= Te6edf3summaryTextTb4b4b4,
Te6edf3style Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3typographyTb4b4b4.Te6edf3bodyMediumTb4b4b4,
Te6edf3color Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3colorSchemeTb4b4b4.Te6edf3onSurfaceVariantTb4b4b4,
Tb4b4b4)
Te6edf3TracerouteCardMetricsTb4b4b4(Te6edf3pointTb4b4b4)
Tb4b4b4}
Tb4b4b4}
T8b949e/** Compact coloured metric indicators (forward hops / return hops / RTT) shown at the bottom of a card. */
Tf0883e@Composable
Tff7b72private Tff7b72fun Td2a8ffTracerouteCardMetricsTb4b4b4(Te6edf3pointTb4b4b4: Te6edf3TraceroutePointTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3pointTb4b4b4.Te6edf3forwardHops Tff7b72=Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3pointTb4b4b4.Te6edf3returnHops Tff7b72=Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3pointTb4b4b4.Te6edf3roundTripSeconds Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tff7b72return
Te6edf3SpacerTb4b4b4(Te6edf3modifier Tff7b72= Te6edf3ModifierTb4b4b4.Te6edf3heightTb4b4b4(T79c0ff4.Te6edf3dpTb4b4b4)Tb4b4b4)
T8b949e// FlowRow so the three metric labels wrap onto additional lines when they don't fit the card width
T8b949e// (e.g. long translated strings), rather than the last item being crushed and wrapped per character (#5743).
Te6edf3FlowRowTb4b4b4(
Te6edf3modifier Tff7b72= Te6edf3ModifierTb4b4b4.Te6edf3fillMaxWidthTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3horizontalArrangement Tff7b72= Te6edf3ArrangementTb4b4b4.Te6edf3spacedByTb4b4b4(T79c0ff1T79c0ff2.Te6edf3dpTb4b4b4)Tb4b4b4,
Te6edf3verticalArrangement Tff7b72= Te6edf3ArrangementTb4b4b4.Te6edf3spacedByTb4b4b4(T79c0ff4.Te6edf3dpTb4b4b4)Tb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3pointTb4b4b4.Te6edf3forwardHopsTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3hops Tff7b72-Tff7b72>
Te6edf3RowTb4b4b4(Te6edf3verticalAlignment Tff7b72= Te6edf3AlignmentTb4b4b4.Te6edf3CenterVerticallyTb4b4b4) Tb4b4b4{
Te6edf3MetricIndicatorTb4b4b4(Te6edf3GraphColorsTb4b4b4.Te6edf3BlueTb4b4b4)
Te6edf3SpacerTb4b4b4(Te6edf3ModifierTb4b4b4.Te6edf3widthTb4b4b4(T79c0ff4.Te6edf3dpTb4b4b4)Tb4b4b4)
Te6edf3TextTb4b4b4(
Te6edf3text Tff7b72= Te6edf3formatStringTb4b4b4(Ta5d6ff"Ta5d6ff%s: %dTa5d6ff"Tb4b4b4, Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_forward_hopsTb4b4b4)Tb4b4b4, Te6edf3hopsTb4b4b4)Tb4b4b4,
Te6edf3style Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3typographyTb4b4b4.Te6edf3labelLargeTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3pointTb4b4b4.Te6edf3returnHopsTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3hops Tff7b72-Tff7b72>
Te6edf3RowTb4b4b4(Te6edf3verticalAlignment Tff7b72= Te6edf3AlignmentTb4b4b4.Te6edf3CenterVerticallyTb4b4b4) Tb4b4b4{
Te6edf3MetricIndicatorTb4b4b4(Te6edf3GraphColorsTb4b4b4.Te6edf3GreenTb4b4b4)
Te6edf3SpacerTb4b4b4(Te6edf3ModifierTb4b4b4.Te6edf3widthTb4b4b4(T79c0ff4.Te6edf3dpTb4b4b4)Tb4b4b4)
Te6edf3TextTb4b4b4(
Te6edf3text Tff7b72= Te6edf3formatStringTb4b4b4(Ta5d6ff"Ta5d6ff%s: %dTa5d6ff"Tb4b4b4, Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_return_hopsTb4b4b4)Tb4b4b4, Te6edf3hopsTb4b4b4)Tb4b4b4,
Te6edf3style Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3typographyTb4b4b4.Te6edf3labelLargeTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3pointTb4b4b4.Te6edf3roundTripSecondsTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3rtt Tff7b72-Tff7b72>
Te6edf3RowTb4b4b4(Te6edf3verticalAlignment Tff7b72= Te6edf3AlignmentTb4b4b4.Te6edf3CenterVerticallyTb4b4b4) Tb4b4b4{
Te6edf3MetricIndicatorTb4b4b4(Te6edf3GraphColorsTb4b4b4.Te6edf3OrangeTb4b4b4)
Te6edf3SpacerTb4b4b4(Te6edf3ModifierTb4b4b4.Te6edf3widthTb4b4b4(T79c0ff4.Te6edf3dpTb4b4b4)Tb4b4b4)
Te6edf3TextTb4b4b4(
Te6edf3text Tff7b72= Te6edf3formatStringTb4b4b4(Ta5d6ff"Ta5d6ff%s: %.1f sTa5d6ff"Tb4b4b4, Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_round_tripTb4b4b4)Tb4b4b4, Te6edf3rttTb4b4b4)Tb4b4b4,
Te6edf3style Tff7b72= Te6edf3MaterialThemeTb4b4b4.Te6edf3typographyTb4b4b4.Te6edf3labelLargeTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
T8b949e/** Builds annotated route text and opens the traceroute detail dialog via the ViewModel. */
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffLongParameterListTa5d6ff"Tb4b4b4)
Tff7b72private Tff7b72fun Td2a8ffshowTracerouteDetailTb4b4b4(
Te6edf3pointTb4b4b4: Te6edf3TraceroutePointTb4b4b4,
Te6edf3viewModelTb4b4b4: Te6edf3MetricsViewModelTb4b4b4,
Te6edf3getUsernameTb4b4b4: Tb4b4b4(Tffa657IntTb4b4b4) Tff7b72-Tff7b72> Tffa657StringTb4b4b4,
Te6edf3headerTowardsTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3headerBackTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3durationTemplateTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3statusGreenTb4b4b4: Te6edf3ColorTb4b4b4,
Te6edf3statusYellowTb4b4b4: Te6edf3ColorTb4b4b4,
Te6edf3statusOrangeTb4b4b4: Te6edf3ColorTb4b4b4,
Te6edf3onViewOnMapTb4b4b4: Tb4b4b4(Te6edf3requestIdTb4b4b4: Tffa657IntTb4b4b4, Te6edf3responseLogUuidTb4b4b4: Tffa657StringTb4b4b4) Tff7b72-Tff7b72> Tffa657UnitTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3result Tff7b72= Te6edf3pointTb4b4b4.Te6edf3result Tff7b72?: Tff7b72return
Tff7b72val Te6edf3route Tff7b72= Te6edf3resultTb4b4b4.Te6edf3fromRadioTb4b4b4.Te6edf3packetTff7b72?.Te6edf3fullRouteDiscovery
Tff7b72val Te6edf3annotatedTb4b4b4: Te6edf3AnnotatedString Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3route Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3routeTb4b4b4.Te6edf3routeTb4b4b4.Te6edf3isNotEmptyTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Te6edf3routeTb4b4b4.Te6edf3route_backTb4b4b4.Te6edf3isNotEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3seconds Tff7b72= Te6edf3pointTb4b4b4.Te6edf3roundTripSeconds Tff7b72?: T79c0ff0.0
Tff7b72val Te6edf3annotatedBase Tff7b72=
Te6edf3annotateTracerouteTb4b4b4(
Te6edf3resultTb4b4b4.Te6edf3fromRadioTb4b4b4.Te6edf3packetTff7b72?.Te6edf3getTracerouteResponseTb4b4b4(
Te6edf3getUsernameTb4b4b4,
Te6edf3headerTowards Tff7b72= Te6edf3headerTowardsTb4b4b4,
Te6edf3headerBack Tff7b72= Te6edf3headerBackTb4b4b4,
Tb4b4b4)Tb4b4b4,
Te6edf3statusGreen Tff7b72= Te6edf3statusGreenTb4b4b4,
Te6edf3statusYellow Tff7b72= Te6edf3statusYellowTb4b4b4,
Te6edf3statusOrange Tff7b72= Te6edf3statusOrangeTb4b4b4,
Tb4b4b4)
Tff7b72val Te6edf3durationText Tff7b72= Te6edf3formatStringTb4b4b4(Te6edf3durationTemplateTb4b4b4, Te6edf3NumberFormatterTb4b4b4.Te6edf3formatTb4b4b4(Te6edf3secondsTb4b4b4, T79c0ff1Tb4b4b4)Tb4b4b4)
Te6edf3buildAnnotatedString Tb4b4b4{
Te6edf3appendTb4b4b4(Te6edf3annotatedBaseTb4b4b4)
Te6edf3appendTb4b4b4(Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff\Ta5d6ffnTffd700$Te6edf3durationTextTa5d6ff"Tb4b4b4)
Tb4b4b4}
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3resultTb4b4b4.Te6edf3fromRadioTb4b4b4.Te6edf3packet
Tff7b72?.Te6edf3getTracerouteResponseTb4b4b4(Te6edf3getUsernameTb4b4b4, Te6edf3headerTowards Tff7b72= Te6edf3headerTowardsTb4b4b4, Te6edf3headerBack Tff7b72= Te6edf3headerBackTb4b4b4)
Tff7b72?.Te6edf3let Tb4b4b4{ Te6edf3AnnotatedStringTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4} Tff7b72?: Tff7b72return
Tb4b4b4}
Tff7b72val Te6edf3overlay Tff7b72=
Te6edf3routeTff7b72?.Te6edf3let Tb4b4b4{
Te6edf3TracerouteOverlayTb4b4b4(
Te6edf3requestId Tff7b72= Te6edf3pointTb4b4b4.Te6edf3requestTb4b4b4.Te6edf3fromRadioTb4b4b4.Te6edf3packetTff7b72?.Te6edf3id Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3forwardRoute Tff7b72= Tffa657itTb4b4b4.Te6edf3routeTb4b4b4,
Te6edf3returnRoute Tff7b72= Tffa657itTb4b4b4.Te6edf3route_backTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Te6edf3viewModelTb4b4b4.Te6edf3showTracerouteDetailTb4b4b4(
Te6edf3annotatedMessage Tff7b72= Te6edf3annotatedTb4b4b4,
Te6edf3requestId Tff7b72= Te6edf3pointTb4b4b4.Te6edf3requestTb4b4b4.Te6edf3fromRadioTb4b4b4.Te6edf3packetTff7b72?.Te6edf3id Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3responseLogUuid Tff7b72= Te6edf3resultTb4b4b4.Te6edf3uuidTb4b4b4,
Te6edf3overlay Tff7b72= Te6edf3overlayTb4b4b4,
Te6edf3onViewOnMap Tff7b72= Te6edf3onViewOnMapTb4b4b4,
Tb4b4b4)
Tb4b4b4}
T8b949e/** Generates a display string and icon based on the route discovery information. */
Tf0883e@Composable
Tff7b72private Tff7b72fun Td2a8ffRouteDiscoveryTff7b72?.Te6edf3getTextAndIconTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3PairTff7b72<Tffa657StringTb4b4b4, Te6edf3ImageVectorTff7b72> Tff7b72= Tff7b72when Tb4b4b4{
Tff7b72this Tff7b72=Tff7b72= Tff7b72null Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_no_responseTb4b4b4) Te6edf3to Te6edf3MeshtasticIconsTb4b4b4.Te6edf3PersonOff
Tb4b4b4}
Te6edf3routeTb4b4b4.Te6edf3size Tff7b72<Tff7b72= T79c0ff2 Tff7b72&Tff7b72& Te6edf3route_backTb4b4b4.Te6edf3size Tff7b72<Tff7b72= T79c0ff2 Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_directTb4b4b4) Te6edf3to Te6edf3MeshtasticIconsTb4b4b4.Te6edf3Group
Tb4b4b4}
Te6edf3routeTb4b4b4.Te6edf3size Tff7b72=Tff7b72= Te6edf3route_backTb4b4b4.Te6edf3size Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72val Te6edf3hops Tff7b72= Te6edf3routeTb4b4b4.Te6edf3size Tff7b72- T79c0ff2
Te6edf3pluralStringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3pluralsTb4b4b4.Te6edf3traceroute_hopsTb4b4b4, Te6edf3hopsTb4b4b4, Te6edf3hopsTb4b4b4) Te6edf3to Te6edf3MeshtasticIconsTb4b4b4.Te6edf3Route
Tb4b4b4}
Tff7b72else Tff7b72-Tff7b72> Tb4b4b4{
Tff7b72val Te6edf3towards Tff7b72= Te6edf3maxOfTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3routeTb4b4b4.Te6edf3size Tff7b72- T79c0ff2Tb4b4b4)
Tff7b72val Te6edf3back Tff7b72= Te6edf3maxOfTb4b4b4(T79c0ff0Tb4b4b4, Te6edf3route_backTb4b4b4.Te6edf3size Tff7b72- T79c0ff2Tb4b4b4)
Te6edf3stringResourceTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3traceroute_diffTb4b4b4, Te6edf3towardsTb4b4b4, Te6edf3backTb4b4b4) Te6edf3to Te6edf3MeshtasticIconsTb4b4b4.Te6edf3Route
Tb4b4b4}
Tb4b4b4}
Served by rngit 1.5.0 - Generated in 0.12s